#include "loading_button_2_p.h"

#include <QMovie>
#include <QMouseEvent>

LoadingButton2::LoadingButton2(QWidget *parent)
    : QPushButton(parent)
    , d_ptr{ new LoadingButton2Private{this} }
{}

LoadingButton2::~LoadingButton2()
{}

void LoadingButton2::setMovie(const QString& filePath)
{
    Q_D(LoadingButton2);

    d->setMovie(new QMovie(filePath));
}

void LoadingButton2::setMovie(QMovie* movie)
{
    Q_D(LoadingButton2);

    d->setMovie(movie);
}

QMovie* LoadingButton2::movie() const
{
    Q_D(const LoadingButton2);
     
    return d->m_pMovie;
}

void LoadingButton2::setTimeout(int timeout)
{
    Q_D(LoadingButton2);

    d->m_nTimeout = timeout;
}

int LoadingButton2::timeout() const
{
    Q_D(const LoadingButton2);

    return d->m_nTimeout;
}

void LoadingButton2::mouseReleaseEvent(QMouseEvent* me)
{
    Q_D(LoadingButton2);

    if (me->button() == Qt::LeftButton && d->startMovie()) {
        d->m_nTimerId = this->startTimer(d->m_nTimeout);
    }

    QPushButton::mouseReleaseEvent(me);
}

void LoadingButton2::timerEvent(QTimerEvent* te)
{
    Q_D(LoadingButton2);

    if (te->timerId() == d->m_nTimerId) {
        d->stopMovie();
        this->killTimer(d->m_nTimerId);
        emit sgnTimeout();
    }

    QPushButton::timerEvent(te);
}

LoadingButton2Private::LoadingButton2Private(LoadingButton2* q)
    : QObject(q)
    , q_ptr{ q } 
    , m_nTimeout{ 1000 }
    , m_nTimerId{ -1 }
    , m_pMovie{ nullptr }
{
}

void LoadingButton2Private::setMovie(QMovie* movie)
{
    if (!movie)
        return;

    if (movie == m_pMovie)
        return;

    if (m_pMovie) {
        m_pMovie->stop();
        m_pMovie->disconnect(this);
    }

    m_pMovie = movie;
    m_pMovie->setParent(this);
    m_pMovie->jumpToFrame(0);

    connect(m_pMovie, &QMovie::frameChanged, this, &LoadingButton2Private::onFrameChanged);
}

bool LoadingButton2Private::startMovie()
{
    Q_Q(LoadingButton2);

    if (m_pMovie) {
        m_originIcon = q->icon();
        m_pMovie->start();
        return true;
    }

    return false;
}

void LoadingButton2Private::stopMovie()
{
    Q_Q(LoadingButton2);

    m_pMovie->stop();
    q->setIcon(m_originIcon);
}

void LoadingButton2Private::onFrameChanged(int frameNum)
{
    Q_Q(LoadingButton2);

    q->setIcon(m_pMovie->currentPixmap());
}
